<?php

class BasketItem extends AppModel {

	var $name = "BasketItem";
	var $recursive = 2;
	
	var $bStored = array();
	var $bDayStored = array();
	var $bTotals = array();
	
	var $belongsTo = array(
		'Member'=>array('foreignKey' => "member_id"),
		'Orderable'=>array('foreignKey' => "orderable_id")
	);
	
	function afterFind($results) {
		if (!empty($results)) {
			if (array_key_exists('BasketItem',$results)) {
				$results['BasketItem']['weight'] = $this->calcWeight($results);
				$results['BasketItem']['total'] = $this->calcTotal($results);
				$results['BasketItem']['tax'] = $this->calcTax($results);
				if (count($results['BasketItem']) == 3) {
					unset($results['BasketItem']);
					$results['BasketItem'] = null;
				}
			} else {
				foreach($results as $num => $result) {
					$results[$num]['BasketItem']['weight'] = $this->calcWeight($result);
					$results[$num]['BasketItem']['total'] = $this->calcTotal($result);
					$results[$num]['BasketItem']['tax'] = $this->calcTax($result);
					if (count($results[$num]['BasketItem']) == 3) {
						unset($results[$num]['BasketItem']);
						$results[$num]['BasketItem'] = null;
					}
				}
			}
		}
		
		return $results;
	}
	
	function calcWeight($result) {
		$ret = 0;
		if (isset($result['Orderable'])) {
			if ($result['BasketItem']['weight'] == 0) { // weight is in default.	It might be zero, but it's time to check.
				$prod = $result['Orderable']['Product'];
				if ($prod['random_weight'] != 0) {// weight is relevant when true
					if ($prod['minimum_weight'] == 0 && $prod['maximum_weight'] == 0) { // weights should not be averaged
						$ret = 1;
					} else {
						$ret = ($prod['minimum_weight'] + $prod['maximum_weight']) / 2;
					}
				}
			} else {
				$ret = $result['BasketItem']['weight'];
			}
		}
		return $ret;
	}
	
	function calcTotal($result) {
		$total = 0;
		if (isset($result['Orderable'])) {
			$total = $result['Orderable']['price'] * $result['BasketItem']['quantity'];
			$w = $this->calcWeight($result);
			$total = ($w == 0) ? $total : $total * $w;
		}
		return $total;
	}
	
	function calcTax($result) {
		$ret = 0;
		if (!isset($result['BasketItem']['total'])) {
			$result['BasketItem']['weight'] = $this->calcWeight($result);
			$result['BasketItem']['total'] = $this->calcTotal($result);
		}
		if (isset($result['Orderable'])) {
			$ret = ($result['Orderable']['Product']['tax_exempt']) ? 0 : $result['BasketItem']['total'] * SALES_TAX;
		}
		return $ret;
	}
	
	function numBaskets($del = null) {
		if ($del === null) { $del = Configure::read('Delivery.delivery_id'); }
		$r = $this->query('SELECT COUNT(DISTINCT Basket.member_id) as BasketsOpen FROM (basket_items AS Basket LEFT JOIN orderables as Orderable ON Basket.orderable_id = Orderable.id) WHERE Orderable.delivery_id = ' . $del);
		return $r[0][0]['BasketsOpen'];
	}
	
	function numProducers($del = null) {
		if ($del === null) { $del = Configure::read('Delivery.delivery_id'); }
		$r = $this->query('SELECT COUNT(DISTINCT Product.producer_id) as BasketsOpen FROM (basket_items AS Basket LEFT JOIN orderables as Orderable ON Basket.orderable_id = Orderable.id LEFT JOIN product_list as Product ON Orderable.product_id = Product.product_id) WHERE Orderable.delivery_id = ' . $del);
		return $r[0][0]['BasketsOpen'];
	}
	
	function _basketTotals($del) {
		$t = array();
		if (!isset($this->bStored[$del])) {
			$r = $this->query('SELECT SUM(Basket.quantity * Orderable.price * 
IF(Product.random_weight,
 IF(Basket.weight < 0, Basket.weight, 
	IF(Product.minimum_weight + Product.maximum_weight = 0, 1, (Product.minimum_weight + Product.maximum_weight)/2)),
1)) as BasketsOpen FROM (basket_items AS Basket LEFT JOIN orderables as Orderable ON Basket.orderable_id = Orderable.id), product_list as Product WHERE Orderable.delivery_id = ' . $del . ' AND Orderable.product_id = Product.product_id GROUP BY Basket.member_id');
			foreach($r as $b) {
				$t[] = $b[0]['BasketsOpen'];
			}
			$this->bStored[$del] = $t;
		}
		return $this->bStored[$del];
	}
	
	function _basketTotalsByDay($day) {
		$t = array();
		if (!isset($this->bDayStored[$day])) {
			$r = $this->query('SELECT SUM(Basket.quantity * Orderable.price * 
IF(Product.random_weight,
 IF(Basket.weight < 0, Basket.weight, 
	IF(Product.minimum_weight + Product.maximum_weight = 0, 1, (Product.minimum_weight + Product.maximum_weight)/2)),
1)) as BasketsOpen FROM (basket_items AS Basket LEFT JOIN orderables as Orderable ON Basket.orderable_id = Orderable.id), product_list as Product WHERE Basket.created > "' . $day . ' 00:00:00" AND Basket.created <= "' . $day . ' 23:59:59" AND Orderable.product_id = Product.product_id GROUP BY Basket.member_id');
		foreach($r as $b) {
			$t[] = $b[0]['BasketsOpen'];
		}
			$this->bDayStored[$day] = $t;
		}
		return $t;
	}
	
	function basketsTotalByDay($del = null) {
		if ($del === null) { $del = Configure::read('Delivery.delivery_id'); }
		//App::import('Model', 'Delivery');
		$d = new Delivery();
		$delInfo = $d->find('Delivery.delivery_id = ' . $del);
		preg_match('/([\d]{4})-([\d]{2})-([\d]{2}) /',$delInfo['Delivery']['order_open'],$start);
		preg_match('/([\d]{4})-([\d]{2})-([\d]{2}) /',$delInfo['Delivery']['pickup_closed'],$end);
		$s = strtotime($start[0]);
		$e = strtotime($end[0]) + 172800;
		$n = $s;
		$t = array();
		while ($n < $e) {
			$v = round(array_sum($this->_basketTotalsByDay(date('Y-m-d',$n)))*100)/100;
			if ($v > 0) { $t[date('m/d',$n)] = $v;}
			$n += 86400;
		}
		return $t;
	}
	
	function basketsTotal($del = null) {
		if (!isset($this->bTotals[$del])) {
			if ($del === null) { $del = Configure::read('Delivery.delivery_id'); }
			$t = $this->_basketTotals($del);
			$this->bTotals[$del] = round(array_sum($t)*100)/100;
		}
		return $this->bTotals[$del];
	}
	
	function avgBasketTotal($del = null) {
		if ($del === null) { $del = Configure::read('Delivery.delivery_id'); }
		$t = $this->basketsTotal($del);
		if (count($this->bStored[$del]) == 0) {
			$ret = 0;
		} else {
			$ret = round($t/count($this->bStored[$del])*100)/100;
		}
		return $ret;
	}
	
	function c_find($where = null, $order = null, $del = null, $page = 1, $limit = 0) {
	
		//$limit = 50; //50 invoices max
	
		if ($del === null) { $del = Configure::read('Delivery.delivery_id'); }
	
		if ($where === null) { $where = '1'; }
		
		if ($limit == 0) {
			$special = 1;
		}
		
		if ($order === null || low($order) == 'member') {
			$order = 'member.last_name, member.first_name, producer.business_name, product_list.product_name';
			if ($limit > 0) {
				$ids = $this->query("SELECT DISTINCT member.member_id from members as member, basket_items, orderables "
					. ' WHERE orderables . delivery_id = ' . $del . ' '
					. ' AND basket_items . orderable_id = orderables . id '
					. ' AND member . member_id = basket_items . member_id '
					. ' ORDER BY member.last_name, member.first_name LIMIT ' . ($page - 1) * $limit . ',' . $limit);
				$in = Set::extract($ids, '{n}.member.member_id');
				$in = '(' . join(',', $in) . ')';
				$special = 'member.member_id IN ' . $in;
			}
		} else if (low($order) == 'producer') {
			$order = 'producer.business_name, member.last_name, member.first_name, product_list.product_name';
			if ($limit > 0) {
				$ids = $this->query("SELECT DISTINCT producer.member_id from members as producer, producers,  basket_items, orderables, product_list "
					. ' WHERE orderables . delivery_id = ' . $del . ' '
					. ' AND product_list . product_id = orderables . product_id '
					. ' AND basket_items . orderable_id = orderables . id '
					. ' AND producers . producer_id = product_list . producer_id '
					. ' AND producer . member_id = producers . member_id '
					. ' ORDER BY producer.business_name LIMIT ' . ($page - 1) * $limit . ',' . $limit);
				$in = Set::extract($ids, '{n}.producer.member_id');
				$in = '(' . join(',', $in) . ')';
				$special = 'producer.member_id IN ' . $in;
			}
		} else if (low($order) == 'product') {
			$order = 'producer.business_name, product_list.product_name, member.last_name, member.first_name';
		}
		
		$sql = 'SELECT 
		product_list . product_name , 
		product_list . maximum_weight , 
		product_list . minimum_weight , 
		product_list . random_weight , 
		product_list . tax_exempt , 
		product_list . producer_id ,
		producer . business_name , 
		producer.work_phone, 
		producer.memb_amt_owed, 
		producer.paid_fee, 
		producer . member_id, 
		producer.email_address, 
		member . first_name , 
		member . last_name , 
		member . member_id , 
		member . address_line1 , 
		member . address_line2 , 
		member . city , 
		member . state , 
		member . zip , 
		member . home_phone , 
		member . work_phone, 
		member . mobile_phone , 
		orderables . price , 
		orderables . priced_by , 
		orderables . ordered_by , 
		orderables . delivery_id , 
		member.email_address, 
		member.memb_amt_owed, 
		member.paid_fee, 
		basket_items . quantity , 
		basket_items . weight , 
		basket_items . missing, 
		basket_items . id, 
		IF(product_list.random_weight,
 IF(basket_items.weight < 0, basket_items.weight, 
	IF(product_list.minimum_weight + product_list.maximum_weight = 0, 1, (product_list.minimum_weight + product_list.maximum_weight)/2)), 0) as weight, (basket_items.quantity * orderables.price * IF(product_list.random_weight,
 IF(basket_items.weight < 0, basket_items.weight, 
	IF(product_list.minimum_weight + product_list.maximum_weight = 0, 1, (product_list.minimum_weight + product_list.maximum_weight)/2)), 1)) as total '
				. ' FROM product_list , basket_items , members AS member , members AS producer , producers , orderables '
				. ' WHERE orderables . delivery_id = ' . $del . ' '
				. ' AND basket_items . orderable_id = orderables . id '
				. ' AND member . member_id = basket_items . member_id '
				. ' AND product_list . product_id = orderables . product_id '
				. ' AND producers . producer_id = product_list . producer_id '
				. ' AND producer . member_id = producers . member_id '
				. ' AND ' . $where . ' AND ' . $special
				. ' ORDER BY ' . $order;
		
		return $this->query($sql);
	}
	
	function breakOutDuplicates($id, $type = 'producer') {
		$del = Configure::read('Delivery.delivery_id');
		$sql = 'SELECT BasketItem.*, Product.maximum_weight, Product.minimum_weight, Product.random_weight FROM basket_items as BasketItem, orderables AS Orderable, product_list as Product
			WHERE BasketItem.orderable_id = Orderable.id AND Orderable.product_id = Product.product_id AND
			Orderable.delivery_id = ' . $del;
		if ($type == 'producer') {
			$sql .= ' AND Product.producer_id = "' . $id . '"';
		} else {
			$sql .= ' AND BasketItem.member_id = "' . $id . '"';
		}
		$items = $this->query($sql);
		foreach($items as $item) {
			if ($item['Product']['random_weight']) {
				if ($item['BasketItem']['weight'] == 0) {
					$w = ($item['Product']['maximum_weight'] + $item['Product']['minimum_weight']) / 2;
					if ($w == 0) { $w = 1; }
					$item['BasketItem']['weight'] = $w;
				}
				$q = $item['BasketItem']['quantity'];
				$item['BasketItem']['quantity'] = 1;
				for ($i = 1; $i <= $q; $i++) {
					$this->id = null;
					if ($i > 1) {
						if (isset($item['BasketItem']['id'])) { unset($item['BasketItem']['id']); }
					}
					$this->save($item);
				}
			}
		}
		return $items;
	}

}

?>
